// 企业级网络请求封装
import { getStorage, removeStorage } from './storage'

// 判断当前平台
const isH5 = process.env.UNI_PLATFORM === 'h5'

// API端点配置
const API_ENDPOINTS = {
  worksheet: isH5 ? '/api/v2/open/worksheet' : (import.meta.env.VITE_API_BASE || 'https://www.dachen.vip/api/v2/open/worksheet'),
  workflow: 'https://www.dachen.vip/api/workflow/hooks',
  // 可以继续添加其他服务的端点
}

// 基础配置
const BASE_CONFIG = {
  // 默认使用worksheet端点，保持向后兼容
  baseURL: API_ENDPOINTS.worksheet,
  timeout: 10000, 
  retryCount: 7, 
  retryDelay: 800 
}

// 请求缓存
const requestCache = new Map()
// 正在进行的请求
const pendingRequests = new Map()
// 请求队列控制
let activeRequests = 0
const MAX_CONCURRENT_REQUESTS = 6

// 生成请求缓存key
const generateCacheKey = (options) => {
  const { url, method = 'GET', data } = options
  return `${method}:${url}:${JSON.stringify(data || {})}`
}

// 延迟函数
const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms))

// 请求拦截器
const requestInterceptor = (options) => {
  // 添加rowid（替代token）
  const rowid = getStorage('rowid')
  if (rowid) {
    options.header = {
      ...options.header,
      'Authorization': `Bearer ${rowid}`,
      'X-User-ID': rowid
    }
  }
  
  // 默认content-type
  if (!options.header?.['content-type']) {
    options.header = {
      ...options.header,
      'content-type': 'application/json'
    }
  }
  
  return options
}

// 响应拦截器
const responseInterceptor = (response, endpoint = 'worksheet') => {
  const { statusCode, data } = response
  
  // 调试信息（生产环境可以关闭）
  if (process.env.NODE_ENV === 'development') {
    console.log('【responseInterceptor】endpoint:', endpoint, 'statusCode:', statusCode, 'data:', data)
  }
  
  // 统一错误处理
  if (statusCode === 401) {
    // rowid过期处理
    removeStorage('rowid')
    removeStorage('userInfo')
    uni.navigateTo({ url: '/pages/login/login' })
    throw new Error('登录已过期')
  }
  
  if (statusCode >= 400) {
    throw new Error(`请求错误: ${statusCode}`)
  }
  
  // 根据不同端点处理响应格式
  if (endpoint === 'workflow') {
    // workflow端点的响应处理（注册等接口）
    // 假设workflow接口直接返回数据，或者有不同的成功标识
    return data
  } else {
    // worksheet端点的响应处理（原有逻辑）
    if (!data.success) {
      uni.showToast({
        title: data.message || '请求失败',
        icon: 'none'
      })
      throw new Error(data.message)
    }
    return data.data
  }
}

// 带重试的请求函数
const requestWithRetry = async (options, endpoint = 'worksheet', retryCount = 0) => {
  try {
    // 控制并发请求数量
    while (activeRequests >= MAX_CONCURRENT_REQUESTS) {
      await delay(100)
    }
    
    activeRequests++
    
    const result = await new Promise((resolve, reject) => {
      // 合并配置
      const config = {
        ...BASE_CONFIG,
        ...options,
        url: options.url.includes('http') ? options.url : BASE_CONFIG.baseURL.trim() + options.url.trim(),
        timeout: options.timeout || BASE_CONFIG.timeout
      }
      
      // 请求拦截
      const finalOptions = requestInterceptor(config)
      
      // 发送请求
      uni.request({
        ...finalOptions,
        success: (response) => {
          try {
            const result = responseInterceptor(response, endpoint)
            resolve(result)
          } catch (error) {
            reject(error)
          }
        },
        fail: (error) => {
          console.log('【uni.request fail】', error)
          reject(error)
        }
      })
    })
    
    activeRequests--
    return result
    
  } catch (error) {
    activeRequests--
    
    // 重试逻辑
    if (retryCount < BASE_CONFIG.retryCount) {
      console.log(`请求失败，第${retryCount + 1}次重试...`)
      await delay(BASE_CONFIG.retryDelay)
      return requestWithRetry(options, endpoint, retryCount + 1)
    }
    
    // 网络错误处理
    if (retryCount >= BASE_CONFIG.retryCount) {
      uni.showToast({
        title: '网络连接失败，请检查网络',
        icon: 'none'
      })
    }
    
    throw error
  }
}

// 带端点参数的请求函数
const requestWithEndpoint = (endpoint, options = {}) => {
  const baseURL = API_ENDPOINTS[endpoint] || BASE_CONFIG.baseURL
  const finalOptions = {
    ...options,
    url: baseURL.trim() + options.url.trim()
  }

  // 生成缓存key
  const cacheKey = generateCacheKey(finalOptions)
  
  // 检查是否有相同请求正在进行
  if (pendingRequests.has(cacheKey)) {
    return pendingRequests.get(cacheKey)
  }
  
  // 检查缓存（只缓存GET请求，且缓存时间不超过30秒）
  if (finalOptions.method === 'GET' || !finalOptions.method) {
    const cached = requestCache.get(cacheKey)
    if (cached && Date.now() - cached.timestamp < 30000) {
      console.log('使用缓存数据:', cacheKey)
      return Promise.resolve(cached.data)
    }
  }
  
  // 创建请求Promise
  const requestPromise = requestWithRetry(finalOptions, endpoint)
    .then(result => {
      // 缓存GET请求结果
      if (finalOptions.method === 'GET' || !finalOptions.method) {
        requestCache.set(cacheKey, {
          data: result,
          timestamp: Date.now()
        })
        
        // 限制缓存数量，防止内存泄漏
        if (requestCache.size > 50) {
          const firstKey = requestCache.keys().next().value
          requestCache.delete(firstKey)
        }
      }
      
      return result
    })
    .finally(() => {
      // 请求完成后从pending中移除
      pendingRequests.delete(cacheKey)
    })
  
  // 将请求添加到pending中
  pendingRequests.set(cacheKey, requestPromise)
  
  return requestPromise
}

// 核心请求函数
const request = (options) => {
  const cacheKey = generateCacheKey(options)
  
  // 检查是否有相同请求正在进行
  if (pendingRequests.has(cacheKey)) {
    return pendingRequests.get(cacheKey)
  }
  
  // 检查缓存（只缓存GET请求，且缓存时间不超过30秒）
  if (options.method === 'GET' || !options.method) {
    const cached = requestCache.get(cacheKey)
    if (cached && Date.now() - cached.timestamp < 30000) {
      console.log('使用缓存数据:', cacheKey)
      return Promise.resolve(cached.data)
    }
  }
  
  // 创建请求Promise
  const requestPromise = requestWithRetry(options, 'worksheet')
    .then(result => {
      // 缓存GET请求结果
      if (options.method === 'GET' || !options.method) {
        requestCache.set(cacheKey, {
          data: result,
          timestamp: Date.now()
        })
        
        // 限制缓存数量，防止内存泄漏
        if (requestCache.size > 50) {
          const firstKey = requestCache.keys().next().value
          requestCache.delete(firstKey)
        }
      }
      
      return result
    })
    .finally(() => {
      // 请求完成后从pending中移除
      pendingRequests.delete(cacheKey)
    })
  
  // 将请求添加到pending中
  pendingRequests.set(cacheKey, requestPromise)
  
  return requestPromise
}

// 清除缓存的方法
const clearCache = (pattern) => {
  if (pattern) {
    // 清除匹配模式的缓存
    for (const key of requestCache.keys()) {
      if (key.includes(pattern)) {
        requestCache.delete(key)
      }
    }
  } else {
    // 清除所有缓存
    requestCache.clear()
  }
}

// 快捷方法
const http = {
  get: (url, params = {}, options = {}) => {
    return request({
      url,
      method: 'GET',
      data: params,
      ...options
    })
  },
  
  post: (url, data = {}, options = {}) => {
    return request({
      url,
      method: 'POST',
      data,
      ...options
    })
  },
  
  put: (url, data = {}, options = {}) => {
    return request({
      url,
      method: 'PUT',
      data,
      ...options
    })
  },
  
  delete: (url, data = {}, options = {}) => {
    return request({
      url,
      method: 'DELETE',
      data,
      ...options
    })
  },
  
  upload: (url, filePath, formData = {}, options = {}) => {
    return new Promise((resolve, reject) => {
      const uploadOptions = {
        url: url.includes('http') ? url : BASE_CONFIG.baseURL + url,
        filePath,
        name: options.name || 'file',
        formData,
        header: {
          'Authorization': `Bearer ${getStorage('rowid') || ''}`,
          'X-User-ID': getStorage('rowid') || '',
          ...options.header
        },
        timeout: options.timeout || 30000, // 上传文件需要更长的超时时间
        success: (response) => {
          try {
            console.log('上传响应:', response);
            const data = typeof response.data === 'string' ? JSON.parse(response.data) : response.data;
            
            // 适配不同的响应格式
            if (response.statusCode === 200) {
              // 如果有data字段，使用data，否则直接使用整个响应
              resolve(data.data || data);
            } else {
              const errorMessage = data.message || data.msg || '上传失败';
              uni.showToast({
                title: errorMessage,
                icon: 'none'
              });
              reject(new Error(errorMessage));
            }
          } catch (error) {
            console.error('解析上传响应失败:', error);
            reject(new Error('上传响应解析失败'));
          }
        },
        fail: (error) => {
          console.error('上传失败:', error);
          uni.showToast({
            title: error.errMsg || '上传失败',
            icon: 'none'
          });
          reject(error);
        }
      };
      
      // 如果有进度回调，添加进度监听
      if (options.onProgress && typeof options.onProgress === 'function') {
        const uploadTask = uni.uploadFile(uploadOptions);
        uploadTask.onProgressUpdate(options.onProgress);
      } else {
        uni.uploadFile(uploadOptions);
      }
    })
  },
  
  // 新增方法：清除缓存
  clearCache,
  
  // 新增方法：预加载请求
  preload: (url, params = {}, method = 'GET') => {
    const requestMethod = method.toLowerCase()
    if (requestMethod === 'post') {
      return http.post(url, params).catch(() => {
        // 预加载失败不处理，避免影响用户体验
      })
    } else {
      return http.get(url, params).catch(() => {
        // 预加载失败不处理，避免影响用户体验
      })
    }
  },

  // 新增方法：支持多端点的请求
  withEndpoint: (endpoint) => ({
    get: (url, params = {}, options = {}) => {
      return requestWithEndpoint(endpoint, {
        url,
        method: 'GET',
        data: params,
        ...options
      })
    },
    
    post: (url, data = {}, options = {}) => {
      return requestWithEndpoint(endpoint, {
        url,
        method: 'POST',
        data,
        ...options
      })
    },
    
    put: (url, data = {}, options = {}) => {
      return requestWithEndpoint(endpoint, {
        url,
        method: 'PUT',
        data,
        ...options
      })
    },
    
    delete: (url, data = {}, options = {}) => {
      return requestWithEndpoint(endpoint, {
        url,
        method: 'DELETE',
        data,
        ...options
      })
    }
  })
}

export default http